package com.kelp.codetoolkit.service.impl

import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.PsiShortNamesCache
import com.intellij.psi.search.searches.AllClassesSearch
import com.kelp.codetoolkit.constant.MethodConstant
import com.kelp.codetoolkit.data.ListCellData
import com.kelp.codetoolkit.renderer.ParamClassListCellRenderer
import com.kelp.codetoolkit.service.MethodDialogHandleService
import java.awt.Dimension
import javax.swing.JList
import javax.swing.JScrollPane
import javax.swing.JTextField

/**
 * @author: liuyuebai
 * @date: 2025/1/24 13:40
 * @description:
 */
class MethodDialogHandleServiceImpl: MethodDialogHandleService {


    override fun filterSearchByCache(searchQuery: String, project: Project):List<String> {
        val shortNamesCache = PsiShortNamesCache.getInstance(project)
        val allClassNames = shortNamesCache.allClassNames
        val toList = allClassNames.asSequence().filter { className -> className.startsWith(searchQuery) }.toList().sorted()
        return toList
    }

    override fun assembleCellData(listClassName:List<String>,page:Int,project: Project): List<ListCellData> {
        val pageSize = MethodConstant.getCommonPageSize()
        var startIndex = page * pageSize
        val endIndex = (startIndex + pageSize).coerceAtMost(listClassName.size)
        val value = endIndex-startIndex
        startIndex -= (11 - value)
        if (startIndex <0){
            startIndex = 0
        }
        val searchScope = GlobalSearchScope.allScope(project)
        val shortNamesCache = PsiShortNamesCache.getInstance(project)
        val dataList:MutableList<ListCellData> = mutableListOf()
        for (i in startIndex until endIndex) {
            val className = listClassName[i]
            val psiClasses = shortNamesCache.getClassesByName(className, searchScope)
            for (psiClass in psiClasses) {
                var packageName = if (psiClass.qualifiedName != null) psiClass.qualifiedName!! else ""
                val lastDotIndex = packageName.lastIndexOf('.')
                if (lastDotIndex > 0) {
                    packageName = packageName.substring(0, lastDotIndex)
                }
                val cellData = ListCellData(className, packageName, psiClass)
                dataList.add(cellData)
            }
        }
        dataList.sortBy { it.shortClassName }
        return dataList
    }


    override fun filterSearchClasses(searchQuery:String,project: Project,page: Int): List<ListCellData> {
        val psiClasses = AllClassesSearch.search(GlobalSearchScope.allScope(project), project)
        // 合并过滤条件，一次性完成过滤
        val filteredClasses = psiClasses.filter { psiClass ->
            val className = psiClass.name
            !className.isNullOrEmpty() && className.startsWith(searchQuery)
        }.sortedBy { psiClass->psiClass.name }
        val commonPageSize = MethodConstant.getCommonPageSize()
        var startIndex = page * commonPageSize
        val endIndex = (startIndex + commonPageSize).coerceAtMost(filteredClasses.size)
        val value = endIndex-startIndex
        startIndex -= (11 - value)
        if (startIndex <0){
            startIndex = 0
        }

       val viewClass =  filteredClasses.subList(startIndex, endIndex)

        val cellDataList:MutableList<ListCellData> = mutableListOf()
        viewClass.forEach { psiClass ->
            var packageName = psiClass.qualifiedName?:""
            val lastDotIndex = packageName.lastIndexOf('.')
            if (lastDotIndex > 0) {
                packageName = packageName.substring(0, lastDotIndex)
            }
            val name = psiClass.name?:""
            val cellData = ListCellData(name,packageName,psiClass)
            cellDataList.add(cellData)
        }

        return cellDataList
    }

    override fun methodParamPopWindow(paramField: JTextField, selectList: JList<ListCellData>, paramScrollPane: JScrollPane) {

        selectList.setVisibleRowCount(MethodConstant.getCommonPageSize())
        paramScrollPane.preferredSize = Dimension(500, 300)
        paramScrollPane.viewport.view = selectList
        val cellRenderer = ParamClassListCellRenderer()
        cellRenderer.setParamScrollPane(paramScrollPane)
        selectList.cellRenderer = cellRenderer
        paramScrollPane.isVisible = true
        val popupFactory = JBPopupFactory.getInstance()
        val currentPopup = popupFactory.createComponentPopupBuilder(paramScrollPane, null)
            .setResizable(true)
            .setMovable(true)
            .createPopup()
        currentPopup.showUnderneathOf(paramField)
    }


}